import { readFileSync } from 'fs';
import * as ssh2 from "ssh2";
import config from "../package.json";
import ui from "./ui";
let meta = ui.meta(import.meta);
let Client = ssh2.default.Client;
// console.log('ssh2', ssh2);
class SftpClass {
    constructor() {
        let user = Object.assign({
            host: 'localhost',
            port: 22,
            username: 'root',
            password: 'root',
            privateKey: ''
        }, config.deploy);
        if (user.privateKey) {//清理password
            user.privateKey = user.privateKey.replace(/^~/, meta.home)
            delete user.password;
            try {
                user.privateKey = readFileSync(user.privateKey);
                //pk 可使用
                delete user.password;
            } catch (error) {
                console.log('pk 异常:', error);
                delete user.privateKey;
            }
        }

        this.user = user;
        this.conn
        console.log('Sftp user:', this.user);
    }
    async upload(file, target, autoclose = true) {
        await this.connect();

        return new Promise((resolve, reject) => {
            this.conn.sftp((err, sftp) => {
                if (err) {
                    reject(err);
                } else {
                    sftp.fastPut(file, target, {}, (err, result) => {
                        if (err) {
                            console.error('上传异常:', err.message)
                            reject(err);
                        } else {
                            console.log('fastPut :: close')
                            autoclose && this.close();
                            resolve(result);
                        }
                    })
                }
            })
        })
    }
    /**
     * 
     * @param shells 
     * const uploadShellList = [
  `cd ${env.DEFAULT_HOST.path}\n`,
  `rm -rf ${env.DEFAULT_HOST.name}.bak\n`,
  `mv ${env.DEFAULT_HOST.name} ${env.DEFAULT_HOST.name}.bak\n`,
  `unzip ${env.DEFAULT_HOST.name}.zip\n`,
  `mv dist ${env.DEFAULT_HOST.name}\n`,
  `rm -rf ${env.DEFAULT_HOST.name}.zip\n`,
  `exit\n`
]
     * @returns 
     */
    async shell(shells = [], autoclose = true) {//删除谨慎操作
        await this.connect();
        if (shells.length) {
            return new Promise((resolve) => {
                let res = [];
                this.conn.shell((err, stream) => {
                    if (err) throw err
                    stream.on('close', () => {
                        console.log('Stream :: close');
                        autoclose && this.close();
                        resolve(res);
                    }).on('data', (data) => {
                        // console.log('Stream :: STDOUT: ' + data)
                        res.push(data.toString());
                    }).stderr.on('data', (data) => {
                        // console.log('Stream :: STDERR: ' + data)
                        res.push(data.toString());
                    })
                    stream.end(shells.join(''))
                })
            })
        }
    }
    async connect() {
        if (this.conn) {
            return this.conn;
        }
        return new Promise((resolve, reject) => {
            const conn = new Client();
            try {
                conn.on('ready', () => {
                    console.log('Client :: ready');
                    this.conn = conn;
                    resolve(conn);
                }).on('end', () => {
                    console.log('Client :: end');
                    this.conn = undefined;
                }).connect(this.user);
            } catch (error) {
                console.error('Client :: error:', error);
                reject(error);
            }
        })
    }
    close() {
        if (this.conn) {
            this.conn.end();
        }
    }
}


export default new SftpClass();
